package com.complaint.dao;

import com.complaint.util.JDBCUtil;

import java.lang.reflect.Field;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.*;

/**
 * BaseDAO 通用DAO层方法
 * aQuery 查询单行单列数据
 * sQuery 查询多行多列数据
 * update 增删改操作
 * */
public class BaseDAO {
    public <T> T aQuery(Class<T> temp, String sql, Object ... args) {
        T t = null;
        Connection conn = JDBCUtil.getConnection();
        PreparedStatement pst = null;
        ResultSet rs = null;
        int rows = 0;

        try {
            pst = conn.prepareStatement(sql);

            // 设置参数
            for (int i = 0; i < args.length; i++) {
                pst.setObject(i+1, args[i]);
            }

            // 查询
            rs = pst.executeQuery();
            if (rs.next()) {
                t = (T) rs.getObject(1);
            }

            rs.close();
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return t;
    }

    public <T> List<T> sQuery(Class temp, String sql, Object ... args) {
        List<T> t = new ArrayList<T>();
        Connection conn = JDBCUtil.getConnection();
        PreparedStatement pst = null;
        ResultSet rs = null;
        int rows = 0;

        try {
            pst = conn.prepareStatement(sql);

            // 设置参数
            for (int i = 0; i < args.length; i++) {
                pst.setObject(i+1, args[i]);
            }

            // 查询
            rs = pst.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();

            int columnCount = metaData.getColumnCount();

            // 封装实体类
            while (rs.next()) {
                // 使用反射
                Object obj = temp.getDeclaredConstructor().newInstance();

                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnName(i);
                    Object value = rs.getObject(columnName);

                    //
                    if (value.getClass().equals(LocalDateTime.class)) {
                        value = Timestamp.valueOf((LocalDateTime) value);
                    }
                    Field field = temp.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(obj,value);
                }
                t.add((T)obj);
            }

            rs.close();
            pst.close();
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return t;
    }

    public int update(String sql, Object ... args) {
        Connection connection = JDBCUtil.getConnection();
        PreparedStatement ps = null;
        int rows = 0;

        try {
            ps = connection.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                ps.setObject(i+1, args[i]);
                System.out.println("times");
            }

            rows = ps.executeUpdate();

            connection.close();
            ps.close();
        } catch (SQLException sqlException){
            sqlException.printStackTrace();
        }

        return rows;
    }
}
